#include <iostream>
using namespace std;

#include "md5/md5.h"

#include "md5er.h"

const int BUF_SIZE = 1024;

unsigned char hexd[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e','f'};
static void digest_to_string(unsigned char digest[16], char str[33]) {
  for (int i=0; i<16; i++) {
    str[2*i] = hexd[(digest[i] & 0xf0) >> 4];
    str[2*i+1] = hexd[digest[i] & 0xf];
  }
  str[32] = '\0';
}

void md5_stream(FILE* fp, char md5[33]) {
  unsigned char digest[16];
  struct MD5Context context;
  MD5Init(&context);

  size_t rb;
  unsigned char buf[BUF_SIZE];
  
  while ((rb = fread(buf, 1, BUF_SIZE, fp)) != 0) {
    MD5Update(&context, buf, rb);
  }

  MD5Final(digest, &context);
  digest_to_string(digest, md5);
}

void md5_file(const char* name, char md5[33]) {
  FILE* fp = fopen(name, "rb");
  md5_stream(fp, md5);
  fclose(fp);
}

#ifdef EXEC
int main (int argc, char* argv[]) {
  if (argc != 2) {
    cerr << "Usage: " << argv[0] << " <file>" << endl;
    return 1;
  }

  char md5[33];
  md5_file(argv[1], md5);
  cout << md5 << "  " << argv[1] << endl;
  return 0;
}
#endif
